<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="UTF-8" />
    <style>
        #canvas{
            border: black 1px solid;
        }
    </style>
    <script type="text/javascript">
        //7个基本形状，及变形后的坐标
        var shap1=[[0,0,1,0,1,1,1,2],[0,1,1,1,2,1,2,0],[0,0,0,1,0,2,1,2],[0,0,1,0,2,0,0,1]];
        var shap2=[[0,0,0,1,0,2,1,0],[0,0,1,0,2,0,2,1],[0,2,1,0,1,1,1,2],[0,0,0,1,1,1,2,1]];
        var shap3=[[0,0,1,0,1,1,2,1],[1,0,1,1,0,1,0,2],[0,0,1,0,1,1,2,1],[1,0,1,1,0,1,0,2]]
        var shap4=[[0,1,1,0,1,1,2,0],[0,0,0,1,1,1,1,2],[0,1,1,0,1,1,2,0],[0,0,0,1,1,1,1,2]];
        var shap5=[[0,0,1,0,0,1,1,1],[0,0,1,0,0,1,1,1],[0,0,1,0,0,1,1,1],[0,0,1,0,0,1,1,1]];
        var shap6=[[0,1,1,1,2,1,1,0],[0,0,0,1,0,2,1,1],[0,0,1,0,2,0,1,1],[1,0,1,1,0,1,1,2]];
        var shap7=[[0,0,1,0,2,0,3,0],[0,0,0,1,0,2,0,3],[0,0,1,0,2,0,3,0],[0,0,0,1,0,2,0,3]];
        var shaps=[shap1,shap2,shap3,shap4,shap5,shap6,shap7];

        //单位长度
        var unitLen=10;
        //画布上下文
        var ctx;
        //定时
        var tid;
        //画布区域对应的数组
        var resultArray=new Array(40);
        function init()
        {
            //获取画布上下文
            ctx=document.getElementById("canvas").getContext('2d');
            //增加按键事件
            document.addEventListener('keydown',moveShape,false);

            //初始化画布区域数组
            for(var i=0;i<40;i++)
            {
                var row=new Array();
                for(var j=0;j<20;j++)
                {
                    row[j]=0;
                }
                resultArray[i]=row;
            }
            //
            startRun=true;
            DrawLine();
            topTrue=true;
            tid=setInterval("DrawTetris();",200);

        }

        //每个形状在画布上相对于初始位置的坐标偏移量
        var rectX=0;
        var rectY=0;

        //形状变形
        var rotate=0;
        //当前形状或变形的初始坐标
        var t;
        //当前形状
        var shape;

        var startRun=true;


        var shapeHeight=0;//当前形状的高度，四个方块的Y坐标的最大差
        //用于产生随机形状
        var randmShape=1;

        //当前形状每个方块的坐标
        var shapeXY=new Array(4);

        //根据坐标绘制形状
        function Draw(){
            var i=0;
            var tempY=0;
            shapeXY=new Array(4);
            for(i=0;i<4;i++){
                DrawRect((t[i*2]+rectX) *unitLen,(t[i*2+1]+rectY)*unitLen);
                var row=new Array(2);
                row[0]=(t[i*2+1]+rectY);
                row[1]=t[i*2]+rectX;
                shapeXY[i]=row;
                //shapeXY[i,0]=(t[i*2+1]+rectY);
                //shapeXY[i,1]=t[i*2];
                if(topTrue==true)
                {
                    if(tempY<(t[i*2+1]+rectY))
                    {
                        tempY=t[i*2+1]+rectY;
                        shapeHeight=tempY+1;
                    }

                }
                else
                {
                    //tempY=rectY;
                }
            }
            //rectY=tempY;
            rectY+=1;

        }

        //根据捕获的按键，判断具体的按键
        function getDirection(event){
            var keyCode = event.which || event.keyCode;
            switch(keyCode){
                case 1:
                case 38:
                case 269: //up
                    return 'up';
                    break;
                case 2:
                case 40:
                case 270:
                    return 'down';
                    break;
                case 3:
                case 37:
                case 271:
                    return 'left';
                    break;
                case 4:
                case 39:
                case 272:
                    return 'right';
                    break;
                case 339: //exit
                case 240: //back
                    return 'back';
                    break;
            }
        }
        
        //根据按键确定执行的操作
        function moveShape(event){
            if(event=='right'||getDirection(event)=='right')
            {
                for(var i=0;i<4;i++){
                    if(t[2*i]+rectX+1>=20 || resultArray[2*i+rectX+1]==1 ){
                        return;
                    }
                }
                rectX+=1;
            }
            if(event=='left'||getDirection(event)=='left')
            {
                for(var i=0;i<4;i++)
                {
                    if(t[2*i]+rectX-1<0 || resultArray[2*i+rectX-1]==1){
                        return;
                    }
                }
                rectX-=1;

            }
            if(event=='up'||getDirection(event)=='up'){
                var mleft=0;
                for(var i=0;i<4;i++){
                    if(t[i*2]+rectX>mleft){
                        mleft=rectX;
                    }
                }
                if(rotate==3){
                    rotate=0;
                }
                else{
                    rotate+=1;
                }
                t=shape[rotate];
                for(var i=0;i<4;i++){

                    //t[2*i]=t[2*i]+mleft;
                    rectX=mleft;
                }

            }

            if(event=='down'||getDirection(event)=='down'){
                clearInterval(tid);
                tid=setInterval("DrawTetris();",50);
            }
        }
        //定时执行的方法
        function DrawTetris(){
            if(CheckBottom()==true) return;
            //t=shape[rotate];
            if(startRun==false){
                ctx.clearRect(shapeXY[0][1]*unitLen-1,shapeXY[0][0]*unitLen-1,unitLen+2,unitLen+2);
                ctx.clearRect(shapeXY[1][1]*unitLen-1,shapeXY[1][0]*unitLen-1,unitLen+2,unitLen+2);
                ctx.clearRect(shapeXY[2][1]*unitLen-1,shapeXY[2][0]*unitLen-1,unitLen+2,unitLen+2);
                ctx.clearRect(shapeXY[3][1]*unitLen-1,shapeXY[3][0]*unitLen-1,unitLen+2,unitLen+2);
            }
            startRun=false;
            //ctx.clearRect(0,0,200,400-(shapeHeight)*10);
            DrawLine();
            var sp=randmShape;
            shape=shaps[sp-1];
            t=shape[rotate];
            Draw();

        }

        var topTrue=false;
        //检查当前形状是否到了画布底部
        function CheckBottom()
        {

            if(topTrue==true){
                startRun=true;
                topTrue=false;
                rectX=9;
                rectY=0;
                randmShape=Math.floor(Math.random()*7+1);

                return true;
            }

            if(rectY+shapeHeight-1>=40 || rectY==0)
            {
                //clearInterval(tid);
                //ctx.clearRect(0,0,200,300);

                if(rectY==0)
                {
                    return false
                }

                CurrentShapeOnBottom();
                return true;
            }
            else
            {
                //形状中的四个方块有一个到了底部，就不能再向下移动
                if(shapeXY[0][0]==39 || shapeXY[1][0]==39 || shapeXY[2][0]==39 || shapeXY[3][0]==39)
                {
                    CurrentShapeOnBottom();
                    return true;
                }
                //形状中的每个方块所在行的下一行，如果已经存在方块，不能再向下移动
                if((resultArray[shapeXY[0][0]+1][shapeXY[0][1]]+resultArray[shapeXY[1][0]+1][shapeXY[1][1]]
                        +resultArray[shapeXY[2][0]+1][shapeXY[2][1]]+resultArray[shapeXY[3][0]+1][shapeXY[3][1]]
                       >=1) )
                {
                    CurrentShapeOnBottom();
                    return true;
                }
                topTrue=false;
                return false;
            }
        }

        //当前形状到达画布底部后进行的操作
        function CurrentShapeOnBottom(){

            resultArray[shapeXY[0][0]][shapeXY[0][1]]=1;
            resultArray[shapeXY[1][0]][shapeXY[1][1]]=1;
            resultArray[shapeXY[2][0]][shapeXY[2][1]]=1;
            resultArray[shapeXY[3][0]][shapeXY[3][1]]=1;

            if(ClearRow()==false){
                return;
            }
            rectY=0;
            rectX=9;
            randmShape=Math.floor(Math.random()*7+1)
            startRun=true;
            topTrue=true;
            clearInterval(tid);
            tid=setInterval("DrawTetris();",200);
        }
        //计分
        var vpoint=0;
        //清除满格行,并计分
        function ClearRow(){
            var row=new Array();
            var spaceRow=new Array();
            var spaceRows=new Array();
            for(var i=0;i<20;i++){
                spaceRow[i]=0;
            }
            row[0]=shapeXY[0][0];
            for(var i=1;i<4;i++){
                for(var j=0;j<row.length;j++){
                    if(row[j]!=shapeXY[i][0]){
                        if(row[j]<shapeXY[i][0]){
                            row.push(shapeXY[i][0]);

                        }
                        else {
                            row.unshift(shapeXY[i][0]);
                        }
                        break;

                    }
                }
            }

            var isNeedRedraw=false;
            for(var i=0;i<row.length;i++){

                var rowState=0;
                for(var j=0;j<20;j++){
                    rowState+=resultArray[row[i]][j];
                }



                if(rowState==20){
                    resultArray.splice(row[i],1);
                    resultArray.unshift(spaceRow);
                    vpoint+=10;
                    document.getElementById("txtPoint").value=vpoint;
                    isNeedRedraw=true;
                }
            }

            if(isNeedRedraw==true){
                ctx.clearRect(0,0,200,400);
                RedrawCanvas();

            }
            else
            {
                if(shapeXY[0][0]==0 || shapeXY[1][0]==0 || shapeXY[2][0]==0 || shapeXY[3][0]==0){
                    document.getElementById("idState").innerText="Game Over";
                    clearInterval(tid);
                    return false;
                }
            }
            return true;
        }

        //清除满格行后，重新绘制画布
        function RedrawCanvas()
        {
            for(var i=0;i<40;i++){
                for(var j=0;j<20;j++){
                    if(resultArray[i][j]==1){
                        DrawRect(j*unitLen,i*unitLen);
                    }
                }
            }
        }
        //绘制形状中的小方格
        function DrawRect(x,y){
            ctx.fillStyle="red";
            ctx.strokeStyle="black";
            ctx.lineWidth=1;
            ctx.fillRect(x,y,10,10);
            ctx.strokeRect(x,y,10,10);
        }

        
        function DrawLine()
        {
            /*
            var i=1;
            for(i=1;i<40;i++)
            {
                ctx.beginPath();
                ctx.strokeStyle="black";
                ctx.lineWidth=1;
                ctx.moveTo(0,i*10);
                ctx.lineTo(200,i*10);
                ctx.stroke();
            }
            */
        }

    </script>

    </head>
<body onload="init()">

    <canvas id="canvas" width="200" height="400">
        浏览器不支持HTML5  Canvas
    </canvas>
    <br>
    <form id="f" name="f" onsubmit="init()">
        <br>
        <input id="btnStart" type="submit" value="开始" />
        <label id="idState"></label>
        <br>
		
        <label>分数：</label>
        <input  id="txtPoint" readonly="true"  value="0" />
        <br>
        <div>
        <input id="btnUp" type="button" onclick="moveShape('up')" value="变换" />
        <input id="btnDown" type="button" onclick="moveShape('down')" value="快速落下" />
        <input id="btnLeft" type="button" onclick="moveShape('left')" value="向左移动" />
        <input id="btnRight" type="button" onclick="moveShape('right')" value="向右移动" />
        </div>
    </form>



</body>
</html>
